iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
Build on Google AI

零預算 NGO 數位轉型挑戰:30 天打造智慧訂房系統系列 第 18 篇

【 Day 18】系統需求規格說明書 (SRD) 整合與全局設定檔 (Config.gs) 設計實作

  • 分享至 

  • xImage
  •  

在系統開發與架構設計中,「軟編碼 (Soft-coding)」 是確保系統長期具備彈性與可維護性的核心原則。在 Build on Google AI 賽道的「NGO 房間與資源預約管理系統」中,我們包含許多商業與營運規則(如開放時段、節數時長、預約天數上限、24 小時違規條款與租用費用)。

今天我們將系統最新的 SRD (Software Requirements Description) 規格(包含四大核心模組 A/B/C/D 與 Data Schema,並採用最新的 Gemini 3.6 Flash 模型)進行全面整合,並在 Google Apps Script 中建立全系統的心臟——Config.gs 設定檔。未來管理員若需要微調營運政策或更換 API 金鑰,只需修改此設定檔,無須動到任何核心業務邏輯程式碼。


1. 系統需求規格說明書 (SRD)

為了讓後續開發(包含使用 Google AI 工具協同編碼)具備清晰且結構化的準則,以下為系統完整的 SRD 規格說明:

1.1 系統架構與技術棧 (Tech Stack)

  • 後端與資料庫:Google Apps Script (GAS) + Google Sheets
  • AI 服務:Google Gemini API (gemini-3.6-flash) via Google AI Studio
  • 通知與對帳:Telegram Bot API + Gmail API

1.2 資料庫 Schema 規範 (Google Sheets)

User_Roles (職工與權限表)

欄位 (Column) 型態 說明 / 允許值
email String 職工 Email (PK)
role String ADMIN / USER
department String 隸屬部門
status String PENDING_APPROVAL / ACTIVE / SUSPENDED
created_at DateTime 帳戶建立時間

Bookings (預約紀錄表)

欄位 (Column) 型態 說明 / 允許值
booking_id String 預約唯一編號 (PK, e.g., BK_1712345678)
room_id String 房間代號 (A1, A2, B1, B2, TALK_ROOM)
user_email String 預約職工 Email
start_time DateTime 預約開始時間
end_time DateTime 預約結束時間
status String APPROVED / CANCELLED_VALID / LATE_CANCELLED / CANCELLED_WAIVED
check_in_status String NOT_CHECKED_IN / CHECKED_IN
purpose String 預約用途說明
created_at DateTime 建立時間
admin_note String 管理員酌情備註

1.3 功能模組需求與 API 介面規格 (System Modules)

模組 A:身分驗證與帳戶生命週期 (Auth & Account Lifecycle)

  1. sendVerificationCode(email):產生 6 位數 OTP 存入 Cache (10分鐘有效),並透過 Gmail 發送驗證信。
  2. verifyOTPAndRegister(email, code, department):驗證 OTP,成功後於 User_Roles 新增 PENDING_APPROVAL 紀錄,並觸發 Telegram 通知管理員。此狀態下阻擋使用者登入與預約。
  3. approveUserAccount(adminEmail, targetEmail):管理員審核通過後將狀態更新為 ACTIVE,並寄送帳戶開通通知信。
  4. updateUserStatus(adminEmail, targetEmail, newStatus):管理員可隨時將帳戶轉為 SUSPENDED(暫停)或刪除該欄紀錄 REMOVED(徹底移除)。

模組 B:預約與時間衝突檢測 (Booking & Collision Detection)

  1. getAvailableSlots(date, roomId):根據 Config 設定(08:00 - 22:00,以 30 分鐘為一節),回傳該房間當日的所有可用時段。
  2. submitNewBooking(userEmail, roomId, startTime, endTime, purpose):
  • 驗證預約天數是否超出 MAX_BOOKING_ADVANCE_DAYS (90天)。
  • 檢查時段是否重疊(兩區間重疊條件:StartA < EndB AND EndA > StartB)。
  • 無衝突則寫入 Bookings 表,狀態設為 APPROVED,並呼叫 Telegram Bot API 發送新預約推播通知至管理員頻道。

模組 C:取消、改期與 24HR 規章 (Cancellation & Reschedule)

  1. cancelBooking(userEmail, bookingId, reason):
  • 計算 (startTime - now) 的小時差。
  • 若 ≥ 24小時:狀態更新為 CANCELLED_VALID,不予計費。
  • 若 < 24小時:狀態更新為 LATE_CANCELLED,視為預約不使用,照樣納入計費。
  • 成功取消後發送確認 Email,並發送 Telegram 訊息告知管理員該預約已被取消。

模組 D:Google AI (Gemini) 整合與月結對帳 (Google AI & Monthly Billing)

  1. callGeminiApi(prompt):封裝最新的 Google Gemini API (gemini-3.6-flash),用於分析預約數據與產生個人化對帳評語。
  2. applyAdminDiscretion(bookingId, adminEmail, note):管理員對特殊情況點擊豁免,將狀態設為 CANCELLED_WAIVED 並填寫備註,於月結單中剔除計費。
  3. generateMonthlyReportAndSendStatements():
  • 每月 1 號自動觸發。
  • 統計全機構職工上月總預約次數、簽到次數、LATE_CANCELLED 次數與總應計費用(每節 HKD $50)。
  • 結合 Gemini API 自動產生溫馨的機構資源運用摘要。
  • 透過 GmailApp 自動寄發格式化的「個人租用對帳月結單」,並發送 Telegram 月結總報表給管理團隊。

2. 系統全局設定檔 (Config.gs) 程式碼實作

請在 Google Apps Script 專案中新增名為 Config.gs 的檔案,並寫入以下程式碼:

/**
 * ==============================================================================
 * 系統全局設定檔 (Config.gs)
 * 專案:NGO 房間與資源預約管理系統 (Build on Google AI Track)
 * 說明:集中管理 SRD 所定義之營運規則參數、最新 Google AI (Gemini 3.6 Flash) 與 Telegram Bot API 金鑰。
 * ==============================================================================
 */

const SYSTEM_CONFIG = {
  // ----------------------------------------------------------------------------
  // 1. 營運規則與時間參數 (Operations Settings)
  // ----------------------------------------------------------------------------
  
  /** 每日開始營業時間 (24小時制,格式 HH:mm) */
  WORK_START_TIME: "08:00",
  
  /** 每日結束營業時間 (24小時制,格式 HH:mm) */
  WORK_END_TIME: "22:00",
  
  /** 每節預約時長(單位:分鐘) */
  SLOT_DURATION_MINUTES: 30,
  
  /** 開放預訂的最長天數(例如:可預訂未來 90 天內的時段) */
  MAX_BOOKING_ADVANCE_DAYS: 90,
  
  /** 預約取消後,改訂新日期的有效期限(單位:天) */
  MAX_RESCHEDULE_DAYS: 60,
  
  /** 每節(30 分鐘)標準租用費用(單位:HKD) */
  FEE_PER_SLOT: 50,
  
  /** 免費/違規取消臨界線(單位:小時,少於 24 小時取消視為預約不使用照樣計費) */
  LATE_CANCELLATION_THRESHOLD_HOURS: 24,

  // ----------------------------------------------------------------------------
  // 2. Google AI (Gemini) 與外部 API 金鑰設定 (API Keys & Integrations)
  // ----------------------------------------------------------------------------
  
  /** 
   * Google Gemini 模型名稱 (指定使用最新的 gemini-3.6-flash)
   */
  GEMINI_MODEL: "gemini-3.6-flash",

  /** 
   * Google Gemini API Key (Build on Google AI 賽道核心)
   * 優先從 Script Properties 讀取,確保金鑰不寫死在程式碼中
   */
  GEMINI_API_KEY: PropertiesService.getScriptProperties().getProperty("GEMINI_API_KEY") || "YOUR_GEMINI_API_KEY_HERE",

  /** 
   * Telegram Bot API Key (用於發送即時審批、預約異動與月結通知)
   */
  TELEGRAM_BOT_TOKEN: PropertiesService.getScriptProperties().getProperty("TELEGRAM_BOT_TOKEN") || "YOUR_TELEGRAM_BOT_TOKEN_HERE",
  
  /** 
   * Telegram 管理員通知頻道/群組 Chat ID
   */
  TELEGRAM_ADMIN_CHAT_ID: PropertiesService.getScriptProperties().getProperty("TELEGRAM_ADMIN_CHAT_ID") || "YOUR_ADMIN_CHAT_ID_HERE",

  /** 
   * Telegram API 基礎 URL 端點
   */
  TELEGRAM_API_BASE_URL: "https://api.telegram.org/bot",

  /** 
   * Google API Key (用於 Google Calendar / Map 等擴充服務)
   */
  GOOGLE_API_KEY: PropertiesService.getScriptProperties().getProperty("GOOGLE_API_KEY") || "YOUR_GOOGLE_API_KEY_HERE",
  
  /** 
   * 主資料庫 Google Sheet ID
   */
  SPREADSHEET_ID: PropertiesService.getScriptProperties().getProperty("SPREADSHEET_ID") || "YOUR_SPREADSHEET_ID_HERE",
  
  /**
   * 系統管理員通知接收 Email
   */
  ADMIN_EMAIL: "admin@ngo.org"
};

/**
 * 取得全局設定物件的封裝函式
 * @returns {Object} 系統設定物件
 */
function getConfig() {
  return SYSTEM_CONFIG;
}

/**
 * 發送 Telegram Bot 訊息輔助函式
 * @param {string} text - 要發送的訊息內容 (支援 HTML / Markdown)
 * @param {string} [chatId] - 目標 Chat ID,若未填則預設發送至管理員頻道
 * @returns {boolean} 是否發送成功
 */
function sendTelegramNotification(text, chatId) {
  const config = getConfig();
  const targetChatId = chatId || config.TELEGRAM_ADMIN_CHAT_ID;
  
  if (!config.TELEGRAM_BOT_TOKEN || config.TELEGRAM_BOT_TOKEN.includes("YOUR_")) {
    Logger.log("⚠️ Telegram Bot Token 未設定,跳過 Telegram 通知發送。");
    return false;
  }

  const url = `${config.TELEGRAM_API_BASE_URL}${config.TELEGRAM_BOT_TOKEN}/sendMessage`;
  const payload = {
    chat_id: targetChatId,
    text: text,
    parse_mode: "HTML"
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const result = JSON.parse(response.getContentText());
    if (result.ok) {
      Logger.log("✅ Telegram 通知發送成功。");
      return true;
    } else {
      Logger.log(`❌ Telegram 通知發送失敗: ${result.description}`);
      return false;
    }
  } catch (error) {
    Logger.log(`❌ 呼叫 Telegram API 發生例外錯誤: ${error.toString()}`);
    return false;
  }
}

/**
 * 檢查系統關鍵設定是否已妥善配置
 * @returns {Boolean} 設定是否完整
 */
function validateConfig() {
  const config = getConfig();
  const requiredKeys = ["GEMINI_API_KEY", "TELEGRAM_BOT_TOKEN", "TELEGRAM_ADMIN_CHAT_ID", "SPREADSHEET_ID"];
  
  for (const key of requiredKeys) {
    if (!config[key] || config[key].includes("YOUR_")) {
      Logger.log(`⚠️ 警告:設定項目 [${key}] 尚未配置正確的值!`);
      return false;
    }
  }
  Logger.log("✅ 系統設定檔驗證成功,所有必要參數、Google AI (Gemini 3.6 Flash) 及 Telegram API 金鑰皆已配置。");
  return true;
}


3. 設定檔參數與 SRD 營運邏輯對照表

以下為 Config.gs 各項參數與 SRD 商業邏輯的映射關係:

設定參數 (Key) SRD 預設值 營運邏輯說明
WORK_START_TIME "08:00" 前端預約日曆每日最早可選擇的時間點。
WORK_END_TIME "22:00" 前端預約日曆每日最晚可預約的時間點。
SLOT_DURATION_MINUTES 30 系統計算時段的最小單位(30 分鐘為一節)。
MAX_BOOKING_ADVANCE_DAYS 90 限制職工最多可預訂未來 90 天內 的房間。
MAX_RESCHEDULE_DAYS 60 預約取消後,紀錄保留 60 天內 可重新指派新日期。
FEE_PER_SLOT 50 月結單計算費用時,每節(30 分鐘)對應的金額(HKD $50)。
LATE_CANCELLATION_THRESHOLD_HOURS 24 臨界線設定,少於 24 小時取消標記為 LATE_CANCELLED 照樣計費。
GEMINI_MODEL "gemini-3.6-flash" 指定最新的 Gemini 3.6 Flash 模型,提供更高品質且更低延遲的文字分析能力。
GEMINI_API_KEY String Build on Google AI 核心金鑰,用於呼叫 Gemini API 進行預約用途審查與月結對帳摘要生成。
TELEGRAM_BOT_TOKEN String Telegram 機器人 Token,用於觸發帳戶審批、預約成功、取消通知與管理員推播。
TELEGRAM_ADMIN_CHAT_ID String Telegram 管理群組 Chat ID,用於接收管理員專屬即時提醒與審批訊息。

4. 小結

今天將 Google AI 模型版本及 Telegram Bot API 設定,並全面完成 SRD (系統需求說明書) 的整合(模組 A/B/C/D 與 Data Schema)。

明天繼續……


上一篇
【Day 17】實戰操作全流程示範:新職工註冊審核、預約週期、權限異動與管理員月結報表
下一篇
【Day 19】後端核心預約邏輯 API (BookingService.gs) 設計與實作
系列文
零預算 NGO 數位轉型挑戰:30 天打造智慧訂房系統 共 21 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言